package data

import (
	"fmt"
	"reflect"

	"gitee.com/miajio/go-util/lib/read"
)

// FileterInterface 过滤结构体接口
type fileterInterface interface {
	fileter(slice interface{}, fileterObj interface{}) ([]interface{}, error)                 // fileter 内核过滤方法
	Fileter(slice interface{}, fileterFunc func(val interface{}) bool) ([]interface{}, error) // Fileter 用户自定义模式的过滤方法
	String(vals []string, obj string) []string                                                // String 去重字符串数组
	Int(vals []int, obj int) []int                                                            // Int 去重整数数组
	Int8(vals []int8, obj int8) []int8                                                        // Int8 去重整数数组
	Int16(vals []int16, obj int16) []int16                                                    // Int8 去重整数数组
	Int32(vals []int32, obj int32) []int32                                                    // Int32 去重整数数组
	Int64(vals []int64, obj int64) []int64                                                    // Int64 去重整数数组
	Uint(vals []uint, obj uint) []uint                                                        // Uint 去重整数数组
	Uint8(vals []uint8, obj uint8) []uint8                                                    // Uint8 去重整数数组
	Uint16(vals []uint16, obj uint16) []uint16                                                // Uint16 去重整数数组
	Uint32(vals []uint32, obj uint32) []uint32                                                // Uint32 去重整数数组
	Uint64(vals []uint64, obj uint64) []uint64                                                // Uint64 去重整数数组
	Byte(vals []byte, obj byte) []byte                                                        // Byte 去重字节数组
	Float32(vals []float32, obj float32) []float32                                            // Float32 去重浮点数组
	Float64(vals []float64, obj float64) []float64                                            // Float64 去重浮点数组
}

// fileter 过滤结构体
type fileter struct{}

// Fileter 过滤操作对象
var Fileter fileterInterface = (*fileter)(nil)

// String 去重字符串数组
func (fileter *fileter) String(vals []string, obj string) []string {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToString(interfaceSlice)
	} else {
		return vals
	}
}

// Int 去重整数数组
func (fileter *fileter) Int(vals []int, obj int) []int {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToInt(interfaceSlice)
	} else {
		return vals
	}
}

// Int8 去重整数数组
func (fileter *fileter) Int8(vals []int8, obj int8) []int8 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToInt8(interfaceSlice)
	} else {
		return vals
	}
}

// Int8 去重整数数组
func (fileter *fileter) Int16(vals []int16, obj int16) []int16 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToInt16(interfaceSlice)
	} else {
		return vals
	}
}

// Int32 去重整数数组
func (fileter *fileter) Int32(vals []int32, obj int32) []int32 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToInt32(interfaceSlice)
	} else {
		return vals
	}
}

// Int64 去重整数数组
func (fileter *fileter) Int64(vals []int64, obj int64) []int64 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToInt64(interfaceSlice)
	} else {
		return vals
	}
}

// Uint 去重整数数组
func (fileter *fileter) Uint(vals []uint, obj uint) []uint {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToUint(interfaceSlice)
	} else {
		return vals
	}
}

// Uint8 去重整数数组
func (fileter *fileter) Uint8(vals []uint8, obj uint8) []uint8 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToUint8(interfaceSlice)
	} else {
		return vals
	}
}

// Uint16 去重整数数组
func (fileter *fileter) Uint16(vals []uint16, obj uint16) []uint16 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToUint16(interfaceSlice)
	} else {
		return vals
	}
}

// Uint32 去重整数数组
func (fileter *fileter) Uint32(vals []uint32, obj uint32) []uint32 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToUint32(interfaceSlice)
	} else {
		return vals
	}
}

// Uint64 去重整数数组
func (fileter *fileter) Uint64(vals []uint64, obj uint64) []uint64 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToUint64(interfaceSlice)
	} else {
		return vals
	}
}

// Byte 去重字节数组
func (fileter *fileter) Byte(vals []byte, obj byte) []byte {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToByte(interfaceSlice)
	} else {
		return vals
	}
}

// Float32 去重浮点数组
func (fileter *fileter) Float32(vals []float32, obj float32) []float32 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToFloat32(interfaceSlice)
	} else {
		return vals
	}
}

// Float64 去重浮点数组
func (fileter *fileter) Float64(vals []float64, obj float64) []float64 {
	if len(vals) > 1 {
		interfaceSlice, _ := fileter.fileter(vals, obj)
		return read.Slice.InterfaceToFloat64(interfaceSlice)
	} else {
		return vals
	}
}

// Fileter 用户自定义模式的过滤方法
// fileterFunc 方法中返回true则会被过滤
func (*fileter) Fileter(slice interface{}, fileterFunc func(val interface{}) bool) ([]interface{}, error) {
	result := make([]interface{}, 0)
	switch reflect.TypeOf(slice).Kind() {
	case reflect.Slice, reflect.Array:
		vals := reflect.ValueOf(slice)
		for i := 0; i < vals.Len(); i++ {
			val := vals.Index(i).Interface()
			if !fileterFunc(val) {
				result = append(result, val)
			}
		}
	default:
		return nil, fmt.Errorf("slice type error")
	}
	return result, nil
}

// fileter 过滤 从slice中过滤为fileterObj的数据
func (*fileter) fileter(slice interface{}, fileterObj interface{}) ([]interface{}, error) {
	result := make([]interface{}, 0)
	switch reflect.TypeOf(slice).Kind() {
	case reflect.Slice, reflect.Array:
		vals := reflect.ValueOf(slice)
		for i := 0; i < vals.Len(); i++ {
			val := vals.Index(i).Interface()
			if val != fileterObj {
				result = append(result, val)
			}
		}
	default:
		return nil, fmt.Errorf("slice type error")
	}
	return result, nil
}
